package com.gitee.deament.server.core.cli.db.list;

import cn.hutool.core.util.NumberUtil;
import com.gitee.deament.server.config.SystemConfig;
import com.gitee.deament.server.core.annotation.CliHander;
import com.gitee.deament.server.core.cli.AbstractCli;
import com.gitee.deament.server.core.data.ConnectData;
import com.gitee.deament.server.core.data.DBData;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.List;

/**
 * LINDEX key index
 * 可用版本： >= 1.0.0
 * 时间复杂度：O(N)， N 为到达下标 index 过程中经过的元素数量。因此，对列表的头元素和尾元素执行 LINDEX 命令，复杂度为O(1)。
 * 返回列表 key 中，下标为 index 的元素。
 *
 * 下标(index)参数 start 和 stop 都以 0 为底，也就是说，以 0 表示列表的第一个元素，以 1 表示列表的第二个元素，以此类推。
 *
 * 你也可以使用负数下标，以 -1 表示列表的最后一个元素， -2 表示列表的倒数第二个元素，以此类推。
 *
 * 如果 key 不是列表类型，返回一个错误。
 *
 * 返回值
 * 列表中下标为 index 的元素。 如果 index 参数的值不在列表的区间范围内(out of range)，返回 nil 。
 */
@CliHander(command = "LINDEX")
public class LINDEXcli extends AbstractCli {

    @Override
    public void executeCli(ChannelHandlerContext channelHandlerContext, String command) {
        List<String> cliValues = getValues(command);
        if (cliValues.size() != 3) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("ERR wrong number of arguments for 'LINDEX' command"));
            return;
        }
        int db = ConnectData.SELECT_DB_STORAGE.getUseDB(channelHandlerContext.channel().id().asLongText());
        DBData dbData = SystemConfig.dbData;
        String key = cliValues.get(1);
        String index = cliValues.get(2);
        if (!NumberUtil.isInteger(index)) {
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("第三个参数不是数字"));
        }
        try {
            List<String> value = SystemConfig.dbData.getList(db, key).getValue();
            if(value==null){
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("(nil)"));
                return ;
            }
            int size=value.size();
            int indexVal=Integer.parseInt(index);
            if(Math.abs(indexVal)>size){
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame("(nil)"));
                return ;
            }
            if(indexVal>=0){
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(value.get(indexVal)));
            }else{
                channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(value.get(size-indexVal)));
            }

        }catch (Exception e){
            channelHandlerContext.channel().writeAndFlush(new TextWebSocketFrame(e.getMessage()));
            return;
        }
    }
}
